
    window.onload = async () => {
    const env = {
        serviceUrl: "https://vjmap.com/server/api/v1",
        accessToken: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJJRCI6MiwiVXNlcm5hbWUiOiJhZG1pbjEiLCJOaWNrTmFtZSI6ImFkbWluMSIsIkF1dGhvcml0eUlkIjoiYWRtaW4iLCJCdWZmZXJUaW1lIjo4NjQwMCwiZXhwIjo0ODEzMjY3NjM3LCJpc3MiOiJ2am1hcCIsIm5iZiI6MTY1OTY2NjYzN30.cDXCH2ElTzU2sQU36SNHWoTYTAc4wEkVIXmBAIzWh6M",
        exampleMapId: "sys_zp",
        assetsPath: "../../assets/",
        ...__env__ // 如果您已私有化部署，需要连接已部署的服务器地址和token，请打开js/env.js,修改里面的参数
    };
    try {
        // 在线效果查看地址: https://vjmap.com/map3d/demo/#/demo/map/threejs/165threeWebglbuffergeometrydrawrange
        // --buffergeometry_drawrange--
        // 下面代码参考threejs官方示例改写 https://threejs.org/examples/#webgl_buffergeometry_drawrange
        let svc = new vjmap3d.Service(env.serviceUrl, env.accessToken);
        let app = new vjmap3d.App(svc, {
            container: "map", // 容器id
            scene: {
                defaultLights: false
            },
            camera: {
                fov: 45,
                near: 1,
                far: 4000,
                position: [0, 0, 1750]
            },
            control: {
                minDistance: 1000,
                maxDistance: 3000
            }
        })
        let scene = app.scene, camera = app.camera, renderer = app.renderer;
        
        
        
        let group;
        const particlesData = [];
        let positions, colors;
        let particles;
        let pointCloud;
        let particlePositions;
        let linesMesh;
        
        const maxParticleCount = 1000;
        let particleCount = 500;
        const r = 800;
        const rHalf = r / 2;
        
        const effectController = {
            showDots: true,
            showLines: true,
            minDistance: 150,
            limitConnections: false,
            maxConnections: 20,
            particleCount: 500
        };
        
        init();
        
        function initGUI() {
        
            const gui = new GUI();
        
            gui.add( effectController, 'showDots' ).onChange( function ( value ) {
        
                pointCloud.visible = value;
        
            } );
            gui.add( effectController, 'showLines' ).onChange( function ( value ) {
        
                linesMesh.visible = value;
        
            } );
            gui.add( effectController, 'minDistance', 10, 300 );
            gui.add( effectController, 'limitConnections' );
            gui.add( effectController, 'maxConnections', 0, 30, 1 );
            gui.add( effectController, 'particleCount', 0, maxParticleCount, 1 ).onChange( function ( value ) {
        
                particleCount = value;
                particles.setDrawRange( 0, particleCount );
        
            } );
        
        }
        
        function init() {
        
            initGUI();
        
            group = new THREE.Group();
            scene.add( group );
        
            const helper = new THREE.BoxHelper( new THREE.Mesh( new THREE.BoxGeometry( r, r, r ) ) );
            helper.material.color.setHex( 0x474747 );
            helper.material.blending = THREE.AdditiveBlending;
            helper.material.transparent = true;
            group.add( helper );
        
            const segments = maxParticleCount * maxParticleCount;
        
            positions = new Float32Array( segments * 3 );
            colors = new Float32Array( segments * 3 );
        
            const pMaterial = new THREE.PointsMaterial( {
                color: 0xFFFFFF,
                size: 3,
                blending: THREE.AdditiveBlending,
                transparent: true,
                sizeAttenuation: false
            } );
        
            particles = new THREE.BufferGeometry();
            particlePositions = new Float32Array( maxParticleCount * 3 );
        
            for ( let i = 0; i < maxParticleCount; i ++ ) {
        
                const x = Math.random() * r - r / 2;
                const y = Math.random() * r - r / 2;
                const z = Math.random() * r - r / 2;
        
                particlePositions[ i * 3 ] = x;
                particlePositions[ i * 3 + 1 ] = y;
                particlePositions[ i * 3 + 2 ] = z;
        
                // add it to the geometry
                particlesData.push( {
                    velocity: new THREE.Vector3( - 1 + Math.random() * 2, - 1 + Math.random() * 2, - 1 + Math.random() * 2 ),
                    numConnections: 0
                } );
        
            }
        
            particles.setDrawRange( 0, particleCount );
            particles.setAttribute( 'position', new THREE.BufferAttribute( particlePositions, 3 ).setUsage( THREE.DynamicDrawUsage ) );
        
            // create the particle system
            pointCloud = new THREE.Points( particles, pMaterial );
            group.add( pointCloud );
        
            const geometry = new THREE.BufferGeometry();
        
            geometry.setAttribute( 'position', new THREE.BufferAttribute( positions, 3 ).setUsage( THREE.DynamicDrawUsage ) );
            geometry.setAttribute( 'color', new THREE.BufferAttribute( colors, 3 ).setUsage( THREE.DynamicDrawUsage ) );
        
            geometry.computeBoundingSphere();
        
            geometry.setDrawRange( 0, 0 );
        
            const material = new THREE.LineBasicMaterial( {
                vertexColors: true,
                blending: THREE.AdditiveBlending,
                transparent: true
            } );
        
            linesMesh = new THREE.LineSegments( geometry, material );
            group.add( linesMesh );
        
           app.signal.onAppUpdate.add(animate)
        
        }
        
        function animate() {
        
            let vertexpos = 0;
            let colorpos = 0;
            let numConnected = 0;
        
            for ( let i = 0; i < particleCount; i ++ )
                particlesData[ i ].numConnections = 0;
        
            for ( let i = 0; i < particleCount; i ++ ) {
        
                // get the particle
                const particleData = particlesData[ i ];
        
                particlePositions[ i * 3 ] += particleData.velocity.x;
                particlePositions[ i * 3 + 1 ] += particleData.velocity.y;
                particlePositions[ i * 3 + 2 ] += particleData.velocity.z;
        
                if ( particlePositions[ i * 3 + 1 ] < - rHalf || particlePositions[ i * 3 + 1 ] > rHalf )
                    particleData.velocity.y = - particleData.velocity.y;
        
                if ( particlePositions[ i * 3 ] < - rHalf || particlePositions[ i * 3 ] > rHalf )
                    particleData.velocity.x = - particleData.velocity.x;
        
                if ( particlePositions[ i * 3 + 2 ] < - rHalf || particlePositions[ i * 3 + 2 ] > rHalf )
                    particleData.velocity.z = - particleData.velocity.z;
        
                if ( effectController.limitConnections && particleData.numConnections >= effectController.maxConnections )
                    continue;
        
                // Check collision
                for ( let j = i + 1; j < particleCount; j ++ ) {
        
                    const particleDataB = particlesData[ j ];
                    if ( effectController.limitConnections && particleDataB.numConnections >= effectController.maxConnections )
                        continue;
        
                    const dx = particlePositions[ i * 3 ] - particlePositions[ j * 3 ];
                    const dy = particlePositions[ i * 3 + 1 ] - particlePositions[ j * 3 + 1 ];
                    const dz = particlePositions[ i * 3 + 2 ] - particlePositions[ j * 3 + 2 ];
                    const dist = Math.sqrt( dx * dx + dy * dy + dz * dz );
        
                    if ( dist < effectController.minDistance ) {
        
                        particleData.numConnections ++;
                        particleDataB.numConnections ++;
        
                        const alpha = 1.0 - dist / effectController.minDistance;
        
                        positions[ vertexpos ++ ] = particlePositions[ i * 3 ];
                        positions[ vertexpos ++ ] = particlePositions[ i * 3 + 1 ];
                        positions[ vertexpos ++ ] = particlePositions[ i * 3 + 2 ];
        
                        positions[ vertexpos ++ ] = particlePositions[ j * 3 ];
                        positions[ vertexpos ++ ] = particlePositions[ j * 3 + 1 ];
                        positions[ vertexpos ++ ] = particlePositions[ j * 3 + 2 ];
        
                        colors[ colorpos ++ ] = alpha;
                        colors[ colorpos ++ ] = alpha;
                        colors[ colorpos ++ ] = alpha;
        
                        colors[ colorpos ++ ] = alpha;
                        colors[ colorpos ++ ] = alpha;
                        colors[ colorpos ++ ] = alpha;
        
                        numConnected ++;
        
                    }
        
                }
        
            }
        
        
            linesMesh.geometry.setDrawRange( 0, numConnected * 2 );
            linesMesh.geometry.attributes.position.needsUpdate = true;
            linesMesh.geometry.attributes.color.needsUpdate = true;
        
            pointCloud.geometry.attributes.position.needsUpdate = true;
        
           
            const time = Date.now() * 0.001;
        
            group.rotation.y = time * 0.1;
        }
    }
    catch (e) {
        console.error(e);
    }
};